// 路由鉴权：项目当中路由能不能被访问的权限（什么条件下可以被访问，什么条件下不可以被访问）
import router from '@/router'
import nprogress from 'nprogress'
import pinia from '@/store'
import useUserStore from './store/modules/user'
// 引入nprogress的样式
import 'nprogress/nprogress.css'
import settings from './settings'
// 去除进度条右侧显示加载中的小圆球
nprogress.configure({ showSpinner: false })

// 获取小仓库（注意：如果在组件中外部获取小仓库的数据，必须先引入大仓库的数据）
let useStore = useUserStore(pinia)

// 全局守卫：项目当中任意路由切换都会触发的钩子
// 全局前置守卫
// router.beforeEach(async (to: any, from: any, next: any) => {
router.beforeEach(async (to: any, _: any, next: any) => {
  // 页签用项目名称+路由的名称进行展示
  document.title = `${settings.title} - ${to.meta.title}`
  // to: 将要访问那个路由
  // from: 从那个路由来
  // next：路由放行函数
  nprogress.start() // 进度条开始
  // 获取token
  let token = useStore.token
  // 获取用户名字
  let username = useStore.username
  if (token) {
    // 登录成功，想访问/login，直接指向首页
    if (to.path == '/login') {
      next({ path: '/' })
    } else {
      // 登录成功，访问其他六个页面，直接放行(排除登录)
      if (username) {
        // 如果直接能获取到用户的信息，那么直接放行
        next()
      } else {
        // 如果没有用户信息，在守卫这里发请求获取了用户信息再放行
        try {
          // 获取用户信息以后再放行
          await useStore.userInfo() // 这里需要userInfo 返回结果才行
          // 特殊情况：刷新的时候如果是异步路由，有可能获取到用户信息，但是异步路由还没有加载完毕，出现白屏的效果
          // next()
          next({...to}) // 保证路由加载完成后再放行
        } catch (error) {
          console.log(error)
          // 获取用户失败提示信息。有两个原因：1. token过期 2. 手动修改了本地token
          // 处理流程：退出登录-> 清空用户相关的数据-> 强制跳转到用户登录页面
          await useStore.userLogout()
          next({ path: '/login', query: { redirect: to.path } }) // 这样写的好处，token被改或者过期之后，用户重新登录还能回到之前的页面
        }
      }
    }
  } else {
    // 用户未登录
    // 在用户未登录的情况下，如果用户直接访问'/login'，没有query参数，那么直接放行
    if (to.path == '/login') {
      next()
    } else {
      // 在用户未登录的情况下，如果用户访问的login，并且带有query参数，那么放行，并且携带query参数
      next({ path: '/login', query: { redirect: to.path } })
    }
  }
})

// 全局后置守卫
// router.afterEach((to: any, from: any, next: any) => { // 为了解决变量定义了没有用的问题, 我们使用占位符
router.afterEach((_: any) => {
  nprogress.done() // 进度条结束
})
